package com.yanyeori.framework.security.service;

import com.yanyeori.framework.core.util.DateUtil;
import com.yanyeori.framework.security.bo.UserDetail;
import com.yanyeori.framework.security.configprop.SecurityConfigProps;
import com.yanyeori.framework.security.database.UserDao;
import com.yanyeori.framework.security.enums.UserStatusEnum;
import com.yanyeori.framework.security.exception.MyUsernameNotFoundException;
import com.yanyeori.framework.security.exception.PwdErrorTimesOverException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

/**
 * 用户信息获取服务
 *
 * @author chenkuan 2020/11/20
 */
@Slf4j
@Component
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private SecurityConfigProps config;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetail userDetail = userDao.getByUsername(username);
        if (userDetail == null) {
            log.warn("No user found with username '{}'", username);
            throw new MyUsernameNotFoundException("No user found with username '{}'", username);
        }
        //用户状态
        if (!UserStatusEnum.ACTIVE.getCode().equals(userDetail.getStatus())) {
            userDetail.setEnabled(false);
            return userDetail;
        }
        //次日重置用户密码错误次数为0
        if (!DateUtil.format(System.currentTimeMillis(), "yyyyMMdd").equals(DateUtil.format(userDetail.getPwdUpdateTime(), "yyyyMMdd"))) {
            userDao.updatePwdErrorTime(username, 0);
        } else {
            //非次日校验用户密码错误次数是否超限
            if (config.getDayPwdErrorTimes() > 0) {
                if (userDetail.getPwdErrorTimes() >= config.getDayPwdErrorTimes()) {
                    log.warn("Username '{}' password error times {} over limit {}", username, userDetail.getPwdErrorTimes(), config.getDayPwdErrorTimes());
                    throw new PwdErrorTimesOverException("Password error times over limit {}", config.getDayPwdErrorTimes());
                }
            }
        }
        return userDetail;
    }
}
